#pragma once

#include "Scene/SceneNodeComponent.h"
#include "Math/Math.h"
#include "TransformComponent.m.h"

//位姿组件，
RCLASS()
class WHENGINE_API RTransformComponent :public RSceneNodeComponent
{
    ROBJECT

public:

    RFUNCTION()
    SVec3 GetPosition() const {return Position;}
    RFUNCTION()
    void SetPosition(const SVec3& InPosition);

    RFUNCTION()
    SQuat GetRotation() const {return Rotation;}
    RFUNCTION()
    void SetRotation(const SQuat& InRotation);

    RFUNCTION()
    SVec3 GetEulerAngleInDegree() const {return EulerAngleInDegree;}
    RFUNCTION()
    void SetEulerAngleInDegree(const SVec3& InEulerAngleInDegree);
    RFUNCTION()
    SVec3 GetScale() const {return Scale;}
    RFUNCTION()
    void SetScale(const SVec3& InScale);

    SMatrix4x4 GetWorldMatrix() const;

    RFUNCTION()
    SVec3 GetForward() const {return Forward;}
    RFUNCTION()
    SVec3 GetUp() const {return Up;}
    RFUNCTION()
    SVec3 GetRight() const {return Right;}

    RFUNCTION()
    SVec3 GetLocalPosition() const {return LocalPosition;}
    RFUNCTION()
    SQuat GetLocalRotation() const {return LocalRotation;}
    RFUNCTION()
    SVec3 GetLocalEulerAngleInDegree() const {return LocalEulerAngleInDegree;}
    RFUNCTION()
    SVec3 GetLocalScale() const {return LocalScale;}

protected:
    //世界坐标系下的位姿
    RFIELD()
    SVec3 Position=SVec3(0,0,0);
    RFIELD()
    SQuat Rotation=SQuat::FromEuler(SVec3(0.0f,0.0f,0.0f));
    //用欧拉角表示的旋转，单位是度
    RFIELD()
    SVec3 EulerAngleInDegree=SVec3(0.0f,0.0f,0.0f);
    RFIELD()
    SVec3 Scale=SVec3(1,1,1);

    //世界坐标系下的前
    RFIELD()
    SVec3 Forward=Coordiante::GetForward();
    //世界坐标系下的上
    RFIELD()
    SVec3 Up=Coordiante::GetUp();
    //世界坐标系下的右
    RFIELD()
    SVec3 Right=Coordiante::GetRight();


    //局部坐标系下的位姿
    RFIELD()
    SVec3 LocalPosition=SVec3(0,0,0);
    RFIELD()
    SQuat LocalRotation=SQuat::FromEuler(SVec3(0.0f,0.0f,0.0f));
    //用欧拉角表示的旋转，单位是度
    RFIELD()
    SVec3 LocalEulerAngleInDegree=SVec3(0.0f,0.0f,0.0f);
    RFIELD()
    SVec3 LocalScale=SVec3(1,1,1);    

public:
    RFUNCTION()
    TSharedObjectPtr<RTransformComponent> GetParent() const {return Parent;}
    
    /// @brief 设置父节点位姿 
    /// @param InParent 父节点位姿 
    /// @param bKeepWorldPosRotationScale 
    /// 如果为true 保持现有的世界坐标/旋转和缩放,如果为false 则保持局部坐标/旋转和缩放
    RFUNCTION()
    void SetParent(
        TSharedObjectPtr<RTransformComponent> InParent
        ,bool bKeepWorldPosRotationScale  
        );



    RFUNCTION()
    int64_t GetChildrenNum() const {return Children.Num();}

    RFUNCTION()
    TSharedObjectPtr<RTransformComponent> GetChild(int64_t Index) const {return Children[Index];}

    RFUNCTION()
    void AddChild(
        TSharedObjectPtr<RTransformComponent> InChild
        ,bool bKeepWorldPosRotationScale  
    );

    RFUNCTION()
    void RemoveChild(TSharedObjectPtr<RTransformComponent> InChild);

protected:
    //父节点的位姿，如果没有父节点，则为空
    RFIELD()
    TSharedObjectPtr<RTransformComponent> Parent;

    //在父节点中的索引
    RFIELD()
    int64_t IndexInParent=-1;

    //子节点的位姿
    RFIELD()
    TVector<TSharedObjectPtr<RTransformComponent>> Children;


    void PostParentPositionChanged();
    void PostParentRotationChanged();
    void PostParentScaleChanged();
};